package com.rabbit.utils;

import io.restassured.RestAssured;
import io.restassured.response.Response;
import io.restassured.specification.RequestSpecification;
import org.apache.http.client.methods.HttpRequestBase;
import org.apache.http.client.utils.URIBuilder;
import org.apache.http.HttpEntity;
import org.apache.http.HttpResponse;
import org.apache.http.client.HttpClient;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.entity.ContentType;
import org.apache.http.entity.StringEntity;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClientBuilder;
import org.apache.http.util.EntityUtils;

import java.io.IOException;
import java.net.URI;
import java.net.URISyntaxException;
import java.util.Map;


/**
 * 使用RestAssured RequestSpecification发送 HTTP 请求;
 * 使用Apache HttpClient发送 HTTP 请求
 * -------------------------------------
 * RestAssured 和 Apache HttpClient共同点：
 * 功能：两者都支持发送各种类型的HTTP请求（GET、POST、PUT、DELETE等），并允许你设置请求头、请求体、查询参数等。
 * 响应处理：两者都允许你获取HTTP响应的状态码、响应头和响应体，并对它们进行处理。
 * 异常处理：两者都提供了处理HTTP请求期间可能发生的异常（如连接超时、服务器错误等）的机制。
 * 社区支持和文档：两者都有广泛的社区支持和详细的文档，使得学习和使用它们变得相对容易。
 * ------------------------------------
 * RestAssured 和 Apache HttpClient区别：
 * 抽象级别和易用性：
 * RestAssured：RestAssured是一个基于Java的DSL（领域特定语言），它提供了更高级别的抽象，使得HTTP请求和响应的处理变得简单和直观。它特别适合用于编写简洁的、可读性强的测试代码或API调用代码。RestAssured也支持JSON和XML的自动序列化和反序列化。
 * Apache HttpClient：Apache HttpClient提供了更底层的HTTP客户端功能，提供了丰富的API来构建和发送HTTP请求，以及处理响应。它提供了更多的配置选项，允许你更精细地控制HTTP连接的各个方面，如超时、重定向、代理等。然而，使用它可能需要编写更多的代码来处理请求的构建和响应的解析。
 */
public class HttpRequestUtils {

    /**
     * 使用RestAssured RequestSpecification发送 HTTP 请求
     *
     * @param method  请求方法，例如 "GET", "POST", "PUT", "DELETE" 等
     * @param path    请求路径
     * @param headers 请求头，可以为 null 或空的 Map
     * @param body    请求体，对于 GET 请求通常为 null，对于 POST/PUT 请求可以是 JSON 字符串或其他序列化对象
     * @param params  请求参数，可以是一个包含键值对的 Map，或者 null
     * @return Rest Assured 的 Response 对象
     */
    public static Response restAssuredSendRequest(String method, String path, Map<String, String> headers, Object body, Map<String, String> params) {
        /*Response response = RestAssured.given()
                .baseUri("http://example.com")
                .path("/api/resource")
                .port(80)
                .header("Content-Type", "application/json")
                .body("{\"key\":\"value\"}")
                .when()
                .post();*/

        RequestSpecification requestSpec = RestAssured.given();
        if (headers != null && !headers.isEmpty()) {
            requestSpec.headers(headers);
        }
        if (body != null) {
            if (method.equalsIgnoreCase("POST") || method.equalsIgnoreCase("PUT")) {
                requestSpec.body(body);
            } else {
                throw new IllegalArgumentException("Request body is not supported");
            }
        }
        if (params != null && !params.isEmpty()) {
            requestSpec.params(params);
        }

        Response response;
        switch (method.toUpperCase()) {
            case "GET":
                response = requestSpec.when().get(path);
                break;
            case "POST":
                response = requestSpec.when().post(path);
                break;
            case "PUT":
                response = requestSpec.when().put(path);
                break;
            case "DELETE":
                response = requestSpec.delete(path);
                break;
            default:
                throw new IllegalArgumentException("Unsupported HTTP method");
        }

        return response;
    }

    /**
     * 使用Apache HttpClient发送HTTP请求
     *
     * @param baseUrl     请求路径
     * @param params      请求参数
     * @param requestBody 请求体
     * @param requestType 请求类型
     * @return 以字符串形式返回响应值
     * @throws IOException,URISyntaxException 抛出异常
     */
    public static String apacheSendHttpRequest(String baseUrl, Map<String, String> params, String requestBody, String requestType) throws IOException, URISyntaxException {
        try (CloseableHttpClient httpClient = HttpClientBuilder.create().build()) {
            URIBuilder uriBuilder = new URIBuilder(baseUrl);
            if (params != null) {
                for (Map.Entry<String, String> entry : params.entrySet()) {
                    uriBuilder.setParameter(entry.getKey(), entry.getValue());
                }
            }
            URI uri = uriBuilder.build();

            HttpRequestBase httpRequest;
            if ("GET".equalsIgnoreCase(requestType)) {
                httpRequest = new HttpGet(uri);
            } else if ("POST".equalsIgnoreCase(requestType)) {
                HttpPost httpPost = new HttpPost(uri);
                StringEntity requestEntity = new StringEntity(requestBody, ContentType.APPLICATION_JSON);
                httpPost.setEntity(requestEntity);
                httpRequest = httpPost;
            } else {
                throw new IllegalArgumentException("Invalid request type: " + requestType);
            }

            HttpResponse response = httpClient.execute(httpRequest);
            HttpEntity responseEntity = response.getEntity();
            String responseString = EntityUtils.toString(responseEntity);
            EntityUtils.consume(responseEntity);

            return responseString;
        }
    }

    /**
     * 使用Apache HttpClient发送POST请求
     */
    public static String sendPostRequest(String url, String requestBody) throws IOException {
        // 创建HttpClient实例
        HttpClient httpClient = HttpClientBuilder.create().build();
        HttpPost httpPost = new HttpPost(url);

        // 设置请求体
        StringEntity requestEntity = new StringEntity(requestBody, ContentType.APPLICATION_JSON);
        httpPost.setEntity(requestEntity);

        // 发送请求并获取响应
        HttpResponse response = httpClient.execute(httpPost);
        HttpEntity responseEntity = response.getEntity();

        // 处理响应结果
        String responseString = EntityUtils.toString(responseEntity);
        // 关闭响应实体流
        EntityUtils.consume(requestEntity);

        return responseString;
    }

    /**
     * 使用Apache HttpClient发送GET请求
     */
    public static String sendGetRequest(String baseUrl, Map<String, String> params) throws IOException, URISyntaxException {
        HttpClient httpClient = HttpClientBuilder.create().build();

        // 使用URIBuilder构建带有参数的URL
        URIBuilder uriBuilder = new URIBuilder(baseUrl);
        if (params != null) {
            for (Map.Entry<String, String> entry : params.entrySet()) {
                uriBuilder.setParameter(entry.getKey(), entry.getValue());
            }
        }
        URI uri = uriBuilder.build();
        HttpGet httpGet = new HttpGet(uri);

        HttpResponse response = httpClient.execute(httpGet);
        HttpEntity responseEntity = response.getEntity();

        String responseString = EntityUtils.toString(responseEntity);
        EntityUtils.consume(responseEntity);

        return responseString;
    }
}
